package it.niedermann.android.markdown.markwon.textwatcher

import android.text.Editable
import android.text.TextWatcher
import it.niedermann.android.markdown.MarkdownUtil
import it.niedermann.android.markdown.markwon.MarkwonMarkdownEditor
import it.niedermann.android.markdown.model.EListType

/**
 * Automatically lowers indention when pressing <kbd>Backspace</kbd> on lists and check lists
 */
class LowerIndentionTextWatcher(
    originalWatcher: TextWatcher,
    private val editText: MarkwonMarkdownEditor
) : InterceptorTextWatcher(originalWatcher) {
    private var backspacePressed = false
    private var cursor = 0
    override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
        if (count == 0 && before == 1) {
            if (editText.selectionStart == editText.selectionEnd) {
                backspacePressed = true
                cursor = start
            }
        }
        originalWatcher.onTextChanged(s, start, before, count)
    }

    override fun afterTextChanged(s: Editable) {
        if (backspacePressed) {
            if (!handleBackspace(s, cursor)) {
                originalWatcher.afterTextChanged(s)
            }
            backspacePressed = false
        } else {
            originalWatcher.afterTextChanged(s)
        }
        editText.setMarkdownStringModel(s)
    }

    private fun handleBackspace(editable: Editable, cursor: Int): Boolean {
        val lineStart = MarkdownUtil.getStartOfLine(editable, cursor)
        val lineEnd = MarkdownUtil.getEndOfLine(editable, cursor)

        // The cursor must be at the end of the line to automatically continue
        if (cursor != lineEnd) {
            return false
        }
        val line = editable.subSequence(lineStart, lineEnd).toString()
        val trimmedLine = line.trim { it <= ' ' }

        // There must be no content in this list item to automatically continue
        if (line.indexOf(trimmedLine) + trimmedLine.length < line.length) {
            return false
        }
        for (listType in EListType.values()) {
            if (listType.listSymbol == trimmedLine) {
                if (trimmedLine.length == EListType.DASH.listSymbol.length) {
                    return lowerIndention(editable, line, lineStart, lineEnd)
                }
            } else if (listType.checkboxUnchecked == trimmedLine || listType.checkboxChecked == trimmedLine) {
                if (trimmedLine.length == EListType.DASH.checkboxUnchecked.length) {
                    return lowerIndention(editable, line, lineStart, lineEnd)
                }
            }
        }
        return false
    }

    private fun lowerIndention(
        editable: Editable,
        line: String,
        lineStart: Int,
        lineEnd: Int
    ): Boolean {
        if (line.startsWith("  ")) {
            editable.insert(lineEnd, " ")
            editable.replace(lineStart, lineStart + 2, "")
            return true
        } else if (line.startsWith(" ")) {
            editable.insert(lineEnd, " ")
            editable.replace(lineStart, lineStart + 1, "")
            return true
        }
        return false
    }
}